import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;

/*
    数据库管理工具
*/
public class DBManager{
    
    private Connection conn;
    private Statement stmt;
    
    //构造方法
    public DBManager(String dbName, String userName, String password)
    throws Exception{
        try{
            Class.forName("com.mysql.jdbc.Driver");
            
            String url = "jdbc:mysql://localhost:3306/" + dbName + "?useSSL=false";
            conn = DriverManager.getConnection(url, userName, password);
            stmt = conn.createStatement();
        }catch(Exception e){
            throw e;
        }
    }
    
    //封装insert，根据tableName与需要insert的map即可将数据插入表中
    public void insert(String tableName, Map<String, Object> map)
    throws Exception{        
        //字段 keys
        String fieldNames = "(" + String.join(", ", map.keySet()) + ")";
        
        //字段值 values
        String[] valuesStr = new String[map.size()];
        int i = 0;
        for(Object item : map.values()){
            valuesStr[i++] = item.toString();
        }
        String values = "(" + String.join(", ", valuesStr) + ")";
        
        //构造insert sql语句        
        String sql = "insert into " + tableName + " " + fieldNames + " values " + values;
        
        try{
            stmt.executeUpdate(sql);
        }catch(Exception e){
            throw e;
        }
    }
    
    //封装select，根据tableName与指定map作为where约束值进行查询
    public ResultSet select(String tableName, Map<String, Object> map)
    throws Exception{
        try{
            String[] args = new String[map.size()];
            int i = 0;
            for(Map.Entry<String, Object> entry : map.entrySet()){
                args[i++] = "" + entry.getKey() + " = " + entry.getValue();
            }
            
            String whereArg = "where " + String.join(" and ", args);
            String sql = "select * from " + tableName;
            sql += " " + whereArg;
            
            return stmt.executeQuery(sql);
        }catch(Exception e){
            throw e;
        }
    }
    
    //封装update，根据tableName，修改值map与条件约束map，更新数据
    public int update(String tableName, Map<String, Object> setMap, Map<String, Object> whereMap)
    throws Exception{
        try{
            //构造修改值
            String[] args_set = new String[setMap.size()];
            int i = 0;
            for(Map.Entry<String, Object> entry : setMap.entrySet()){
                args_set[i++] = "" + entry.getKey() + " = " + entry.getValue();
            }
            String setArg = "set " + String.join(", ", args_set);
            
            //构造条件约束
            String[] args_where = new String[whereMap.size()];
            i = 0;
            for(Map.Entry<String, Object> entry : whereMap.entrySet()){
                args_where[i++] = "" + entry.getKey() + " = " + entry.getValue();
            }
            String whereArg = "where " + String.join(" and ", args_where);
            
            //构造sql语句
            String sql = "update " + tableName + " " + setArg + " " + whereArg;
            
            return stmt.executeUpdate(sql);
        }catch(Exception e){
            throw e;
        }
    }
    
    public void close()
    throws Exception{
        try{
            stmt.close();
            conn.close();
        }catch(Exception e){
            throw e;
        }
    }
    
}